/*     */ package com.zimbra.cs.account.ldap;
/*     */ 
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.DateUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.GalContact;
/*     */ import com.zimbra.cs.account.GalContact.Visitor;
/*     */ import com.zimbra.cs.account.Provisioning.SearchGalResult;
/*     */ import com.zimbra.cs.account.gal.GalOp;
/*     */ import com.zimbra.cs.account.gal.GalParams.ExternalGalParams;
/*     */ import com.zimbra.cs.account.gal.GalUtil;
/*     */ import com.zimbra.cs.account.krb5.Krb5Login;
/*     */ import com.zimbra.cs.gal.GalSearchConfig;
/*     */ import com.zimbra.cs.gal.GalSearchConfig.GalType;
/*     */ import com.zimbra.cs.gal.GalSearchParams;
/*     */ import com.zimbra.cs.ldap.IAttributes;
/*     */ import com.zimbra.cs.ldap.LdapClient;
/*     */ import com.zimbra.cs.ldap.LdapException.LdapEntryNotFoundException;
/*     */ import com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException;
/*     */ import com.zimbra.cs.ldap.LdapServerConfig.ExternalLdapConfig;
/*     */ import com.zimbra.cs.ldap.LdapUsage;
/*     */ import com.zimbra.cs.ldap.LdapUtil;
/*     */ import com.zimbra.cs.ldap.SearchLdapOptions;
/*     */ import com.zimbra.cs.ldap.SearchLdapOptions.SearchLdapVisitor;
/*     */ import com.zimbra.cs.ldap.ZAttributes;
/*     */ import com.zimbra.cs.ldap.ZLdapContext;
/*     */ import com.zimbra.cs.ldap.ZLdapFilterFactory;
/*     */ import com.zimbra.cs.ldap.ZLdapFilterFactory.FilterId;
/*     */ import com.zimbra.cs.ldap.ZSearchScope;
/*     */ import java.io.IOException;
/*     */ import java.security.PrivilegedActionException;
/*     */ import java.security.PrivilegedExceptionAction;
/*     */ import java.util.Date;
/*     */ import java.util.Map;
/*     */ import javax.security.auth.login.LoginException;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class LdapGalSearch
/*     */ {
/*     */   public static Provisioning.SearchGalResult searchLdapGal(GalParams.ExternalGalParams galParams, GalOp galOp, String n, int maxResults, LdapGalMapRules rules, String token, GalContact.Visitor visitor)
/*     */     throws ServiceException
/*     */   {
/*  69 */     String[] url = galParams.url();
/*  70 */     String base = galParams.searchBase();
/*  71 */     String filter = galParams.filter();
/*     */     
/*  73 */     Provisioning.SearchGalResult result = Provisioning.SearchGalResult.newSearchGalResult(visitor);
/*  74 */     String tokenize = GalUtil.tokenizeKey(galParams, galOp);
/*  75 */     result.setTokenizeKey(tokenize);
/*     */     
/*  77 */     if ((url == null) || (url.length == 0) || (base == null) || (filter == null)) {
/*  78 */       if ((url == null) || (url.length == 0))
/*  79 */         ZimbraLog.gal.warn("searchLdapGal url is null");
/*  80 */       if (base == null)
/*  81 */         ZimbraLog.gal.warn("searchLdapGal base is null");
/*  82 */       if (filter == null)
/*  83 */         ZimbraLog.gal.warn("searchLdapGal queryExpr is null");
/*  84 */       return result;
/*     */     }
/*     */     
/*  87 */     if (filter.indexOf("(") == -1) {
/*  88 */       String queryExpr = GalSearchConfig.getFilterDef(filter);
/*  89 */       if (queryExpr != null)
/*  90 */         filter = queryExpr;
/*     */     }
/*  92 */     String query = GalUtil.expandFilter(tokenize, filter, n, token);
/*     */     
/*  94 */     String authMech = galParams.credential().getAuthMech();
/*  95 */     if (authMech.equals("kerberos5")) {
/*  96 */       searchLdapGalKrb5(galParams, galOp, query, maxResults, rules, token, result);
/*     */     } else
/*  98 */       searchLdapGal(galParams, galOp, query, maxResults, rules, token, result);
/*  99 */     return result;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static void searchLdapGalKrb5(GalParams.ExternalGalParams galParams, GalOp galOp, String query, int maxResults, LdapGalMapRules rules, String token, Provisioning.SearchGalResult result)
/*     */     throws ServiceException
/*     */   {
/*     */     try
/*     */     {
/* 112 */       LdapGalCredential credential = galParams.credential();
/* 113 */       Krb5Login.performAs(credential.getKrb5Principal(), credential.getKrb5Keytab(), new SearchGalAction(galParams, galOp, query, maxResults, rules, token, result));
/*     */     }
/*     */     catch (LoginException le) {
/* 116 */       throw ServiceException.FAILURE("login failed, unable to search GAL", le);
/*     */     }
/*     */     catch (PrivilegedActionException pae)
/*     */     {
/* 120 */       Exception e = pae.getException();
/* 121 */       if ((e instanceof ServiceException)) {
/* 122 */         throw ((ServiceException)e);
/*     */       }
/* 124 */       throw ServiceException.FAILURE("caught exception, unable to search GAL", e);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   static class SearchGalAction
/*     */     implements PrivilegedExceptionAction
/*     */   {
/*     */     GalParams.ExternalGalParams galParams;
/*     */     
/*     */     GalOp galOp;
/*     */     
/*     */     String query;
/*     */     
/*     */     int maxResults;
/*     */     LdapGalMapRules rules;
/*     */     String token;
/*     */     Provisioning.SearchGalResult result;
/*     */     
/*     */     SearchGalAction(GalParams.ExternalGalParams arg_galParams, GalOp arg_galOp, String arg_query, int arg_maxResults, LdapGalMapRules arg_rules, String arg_token, Provisioning.SearchGalResult arg_result)
/*     */     {
/* 145 */       this.galParams = arg_galParams;
/* 146 */       this.galOp = arg_galOp;
/* 147 */       this.query = arg_query;
/* 148 */       this.maxResults = arg_maxResults;
/* 149 */       this.rules = arg_rules;
/* 150 */       this.token = arg_token;
/* 151 */       this.result = arg_result;
/*     */     }
/*     */     
/*     */     public Object run() throws ServiceException {
/* 155 */       LdapGalSearch.searchLdapGal(this.galParams, this.galOp, this.query, this.maxResults, this.rules, this.token, this.result);
/* 156 */       return null;
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static void searchLdapGal(GalParams.ExternalGalParams galParams, GalOp galOp, String query, int maxResults, LdapGalMapRules rules, String token, Provisioning.SearchGalResult result)
/*     */     throws ServiceException
/*     */   {
/* 169 */     ZLdapContext zlc = null;
/*     */     try {
/* 171 */       LdapGalCredential credential = galParams.credential();
/* 172 */       LdapServerConfig.ExternalLdapConfig ldapConfig = new LdapServerConfig.ExternalLdapConfig(galParams.url(), galParams.requireStartTLS(), credential.getAuthMech(), credential.getBindDn(), credential.getBindPassword(), rules.getBinaryLdapAttrs(), "external GAL");
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 178 */       zlc = LdapClient.getExternalContext(ldapConfig, LdapUsage.fromGalOpLegacy(galOp));
/* 179 */       searchGal(zlc, GalSearchConfig.GalType.ldap, galParams.pageSize(), galParams.searchBase(), query, maxResults, rules, token, result);
/*     */ 
/*     */ 
/*     */ 
/*     */     }
/*     */     finally
/*     */     {
/*     */ 
/*     */ 
/*     */ 
/* 189 */       LdapClient.closeContext(zlc);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void galSearch(GalSearchParams params)
/*     */     throws ServiceException
/*     */   {
/* 203 */     String authMech = params.getConfig().getAuthMech();
/* 204 */     if (authMech.equals("kerberos5")) {
/* 205 */       galSearchKrb5(params);
/*     */     } else {
/* 207 */       doGalSearch(params);
/*     */     }
/*     */   }
/*     */   
/*     */   private static void doGalSearch(GalSearchParams params) throws ServiceException {
/* 212 */     ZLdapContext zlc = null;
/*     */     try {
/* 214 */       GalSearchConfig cfg = params.getConfig();
/* 215 */       GalSearchConfig.GalType galType = params.getConfig().getGalType();
/*     */       
/* 217 */       if (galType == GalSearchConfig.GalType.zimbra) {
/* 218 */         zlc = LdapClient.getContext(LdapUsage.fromGalOp(params.getOp()));
/*     */       } else {
/* 220 */         LdapServerConfig.ExternalLdapConfig ldapConfig = new LdapServerConfig.ExternalLdapConfig(cfg.getUrl(), cfg.getStartTlsEnabled(), cfg.getAuthMech(), cfg.getBindDn(), cfg.getBindPassword(), cfg.getRules().getBinaryLdapAttrs(), "external GAL");
/*     */         
/*     */ 
/*     */ 
/*     */ 
/* 225 */         zlc = LdapClient.getExternalContext(ldapConfig, LdapUsage.fromGalOp(params.getOp()));
/*     */       }
/*     */       
/* 228 */       String fetchEntryByDn = params.getSearchEntryByDn();
/* 229 */       if (fetchEntryByDn == null) {
/* 230 */         searchGal(zlc, galType, cfg.getPageSize(), cfg.getSearchBase(), params.generateLdapQuery(), params.getLimit(), cfg.getRules(), params.getSyncToken(), params.getResult());
/*     */ 
/*     */ 
/*     */ 
/*     */       }
/*     */       else
/*     */       {
/*     */ 
/*     */ 
/*     */ 
/* 240 */         getGalEntryByDn(zlc, galType, fetchEntryByDn, cfg.getRules(), params.getResult());
/*     */       }
/*     */     } finally {
/* 243 */       LdapClient.closeContext(zlc);
/*     */     }
/*     */   }
/*     */   
/*     */   private static void galSearchKrb5(GalSearchParams params)
/*     */     throws ServiceException
/*     */   {
/*     */     try
/*     */     {
/* 252 */       String krb5Principal = params.getConfig().getKerberosPrincipal();
/* 253 */       String krb5Keytab = params.getConfig().getKerberosKeytab();
/* 254 */       Krb5Login.performAs(krb5Principal, krb5Keytab, new GalSearchAction(params));
/*     */     } catch (LoginException le) {
/* 256 */       throw ServiceException.FAILURE("login failed, unable to search GAL", le);
/*     */     }
/*     */     catch (PrivilegedActionException pae)
/*     */     {
/* 260 */       Exception e = pae.getException();
/* 261 */       if ((e instanceof ServiceException)) {
/* 262 */         throw ((ServiceException)e);
/*     */       }
/* 264 */       throw ServiceException.FAILURE("caught exception, unable to search GAL", e);
/*     */     }
/*     */   }
/*     */   
/*     */   static class GalSearchAction implements PrivilegedExceptionAction
/*     */   {
/*     */     GalSearchParams mParams;
/*     */     
/*     */     GalSearchAction(GalSearchParams params) {
/* 273 */       this.mParams = params;
/*     */     }
/*     */     
/*     */     public Object run() throws ServiceException, IOException {
/* 277 */       LdapGalSearch.doGalSearch(this.mParams);
/* 278 */       return null;
/*     */     }
/*     */   }
/*     */   
/*     */   private static class SearhcGalVisitor extends SearchLdapOptions.SearchLdapVisitor
/*     */   {
/*     */     private ZLdapContext zlc;
/*     */     private GalSearchConfig.GalType galType;
/*     */     private String base;
/*     */     private LdapGalMapRules rules;
/*     */     private Provisioning.SearchGalResult result;
/*     */     
/*     */     private SearhcGalVisitor(ZLdapContext zlc, GalSearchConfig.GalType galType, String base, LdapGalMapRules rules, Provisioning.SearchGalResult result)
/*     */     {
/* 292 */       super();
/*     */       
/* 294 */       this.zlc = zlc;
/* 295 */       this.galType = galType;
/* 296 */       this.base = base;
/* 297 */       this.rules = rules;
/* 298 */       this.result = result;
/*     */     }
/*     */     
/*     */     public void visit(String dn, IAttributes ldapAttrs)
/*     */     {
/* 303 */       GalContact lgc = new GalContact(this.galType, dn, this.rules.apply(this.zlc, this.base, dn, ldapAttrs));
/* 304 */       String mts = (String)lgc.getAttrs().get("modifyTimeStamp");
/* 305 */       this.result.setToken(LdapUtil.getLaterTimestamp(this.result.getToken(), mts));
/* 306 */       String cts = (String)lgc.getAttrs().get("createTimeStamp");
/* 307 */       this.result.setToken(LdapUtil.getLaterTimestamp(this.result.getToken(), cts));
/*     */       try {
/* 309 */         this.result.addMatch(lgc);
/*     */       } catch (ServiceException e) {
/* 311 */         ZimbraLog.gal.warn("unable to add GAL match", e);
/*     */       }
/* 313 */       ZimbraLog.gal.debug("dn=" + dn + ", mts=" + mts + ", cts=" + cts);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void searchGal(ZLdapContext zlc, GalSearchConfig.GalType galType, int pageSize, String base, String query, int maxResults, LdapGalMapRules rules, String token, Provisioning.SearchGalResult result)
/*     */     throws ServiceException
/*     */   {
/* 328 */     String tk = (token != null) && (!token.equals("")) ? token : "19700101000000Z";
/* 329 */     result.setToken(tk);
/*     */     
/* 331 */     String[] reqAttrs = rules.getLdapAttrs();
/*     */     
/* 333 */     if (ZimbraLog.gal.isDebugEnabled()) {
/* 334 */       StringBuffer returnAttrs = new StringBuffer();
/* 335 */       for (String a : reqAttrs) {
/* 336 */         returnAttrs.append(a + ",");
/*     */       }
/*     */       
/* 339 */       zlc.debug();
/* 340 */       ZimbraLog.gal.debug("searchGal: , page size=" + pageSize + ", max results=" + maxResults + ", base=" + base + ", query=" + query + ", attrs=" + returnAttrs);
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 348 */     SearhcGalVisitor visitor = new SearhcGalVisitor(zlc, galType, base, rules, result, null);
/*     */     
/* 350 */     SearchLdapOptions searchOpts = new SearchLdapOptions(base, ZLdapFilterFactory.getInstance().fromFilterString(ZLdapFilterFactory.FilterId.GAL_SEARCH, query), reqAttrs, maxResults, null, ZSearchScope.SEARCH_SCOPE_SUBTREE, visitor);
/*     */     
/*     */ 
/*     */ 
/* 354 */     searchOpts.setResultPageSize(pageSize);
/*     */     try
/*     */     {
/* 357 */       zlc.searchPaged(searchOpts); } catch (LdapException.LdapSizeLimitExceededException sle) { boolean gotNewToken;
/*     */       String newToken;
/* 359 */       Date parsedToken; long ts; result.setHadMore(true); } catch (ServiceException e) { boolean gotNewToken;
/*     */       String newToken;
/* 361 */       Date parsedToken; long ts; throw ServiceException.FAILURE("unable to search gal", e);
/*     */     } finally {
/* 363 */       boolean gotNewToken = true;
/* 364 */       String newToken = result.getToken();
/* 365 */       if ((newToken == null) || ((token != null) && (token.equals(newToken))) || (newToken.equals("19700101000000Z"))) {
/* 366 */         gotNewToken = false;
/*     */       }
/* 368 */       if (gotNewToken) {
/* 369 */         Date parsedToken = DateUtil.parseGeneralizedTime(newToken, false);
/* 370 */         if (parsedToken != null) {
/* 371 */           long ts = parsedToken.getTime();
/* 372 */           ts += 1000L;
/*     */           
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 378 */           result.setToken(DateUtil.toGeneralizedTime(new Date(ts)));
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void getGalEntryByDn(ZLdapContext zlc, GalSearchConfig.GalType galType, String dn, LdapGalMapRules rules, Provisioning.SearchGalResult result)
/*     */     throws ServiceException
/*     */   {
/* 394 */     String[] reqAttrs = rules.getLdapAttrs();
/*     */     
/* 396 */     if (ZimbraLog.gal.isDebugEnabled()) {
/* 397 */       StringBuffer returnAttrs = new StringBuffer();
/* 398 */       for (String a : reqAttrs) {
/* 399 */         returnAttrs.append(a + ",");
/*     */       }
/*     */       
/* 402 */       zlc.debug();
/* 403 */       ZimbraLog.gal.debug("getGalEntryByDn: , dn=" + dn + ", attrs=" + returnAttrs);
/*     */     }
/*     */     
/*     */ 
/*     */ 
/* 408 */     SearhcGalVisitor visitor = new SearhcGalVisitor(zlc, galType, null, rules, result, null);
/*     */     try
/*     */     {
/* 411 */       ZAttributes attrs = zlc.getAttributes(dn, reqAttrs);
/* 412 */       visitor.visit(dn, attrs);
/*     */     } catch (LdapException.LdapEntryNotFoundException e) {
/* 414 */       ZimbraLog.gal.debug("getGalEntryByDn: no such dn: " + dn, e);
/*     */     } catch (ServiceException e) {
/* 416 */       throw ServiceException.FAILURE("unable to search gal", e);
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/account/ldap/LdapGalSearch.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */